using System;

namespace Gadgeteer.Modules.Community.XBee
{
    /// <summary>
    /// Builds typed messages that span multiple bytes
    /// </summary>
    public static class MultipartMessageBuilder
    {
        /// <summary>
        /// Build a broadcast transmit request array of typed messages
        /// </summary>
        /// <param name="data">payload</param>
        /// <param name="messageDataType">data type of message</param>
        /// <param name="correlationId">corrlationId</param>
        /// <returns>Array of typed messages to be sent</returns>
        public static TransmitRequest[] BuildMultipartBroadcastMessage(byte[] data, MessageDataTypeEnum messageDataType, ushort correlationId)
        {
            return BuildMultipartMessage(null, data, messageDataType, correlationId);
        }

        /// <summary>
        /// Build a transmit request array of typed messages
        /// </summary>
        /// <param name="destinationNode">the node messages are sent to</param>
        /// <param name="data">payload</param>
        /// <param name="messageDataType">data type of message</param>
        /// <param name="correlationId">corrlationId</param>
        /// <returns>Array of typed messages to be sent</returns>
        public static TransmitRequest[] BuildMultipartMessage(NodeDescription destinationNode, byte[] data, MessageDataTypeEnum messageDataType, ushort correlationId)
        {
            // TODO: get this by querying the XBee's Message Size 
            // 5 additional bytes for multipart messages
            int maxMessageSize = 100 - 17 - 5;
            int numPackets = (int)Math.Ceiling((double)data.Length / (double)maxMessageSize);
            int totalMessageSize = data.Length + (5 * numPackets);
            TransmitRequest[] results = new TransmitRequest[numPackets];
            int bytesInCurrMessage = maxMessageSize;
            int currIndex = 0;

            byte totalMessageSizeLSB = (byte)totalMessageSize;
            totalMessageSize >>= 8;
            byte totalMessageSizeMSB = (byte)totalMessageSize;

            for (int i = 0; i < results.Length; i++)
            {
                bytesInCurrMessage = data.Length - currIndex >= maxMessageSize ? maxMessageSize : data.Length - currIndex;
                byte[] payload = new byte[bytesInCurrMessage + 5];

                payload[0] = (byte)APIMessageEnum.MultiPartMessage;
                payload[1] = (byte)results.Length;
                payload[2] = (byte)i;
                payload[3] = (byte)messageDataType;

                Array.Copy(data, currIndex, payload, 4, bytesInCurrMessage);

                currIndex += bytesInCurrMessage;

                if (null == destinationNode)
                {
                    results[i] = new TransmitRequest { Message = APIMessageBuilder.BuildBroadcastTransmitRequest(payload, correlationId) };
                }
                else
                {
                    results[i] = new TransmitRequest { Message = APIMessageBuilder.BuildTransmitRequest(destinationNode, payload, correlationId) };
                }
            }

            return results;
        }
    }
}
